package com.threeti.mecool.core.domain.model.project;

import com.threeti.mecool.core.domain.model.acl.User;
import com.threeti.mecool.core.exception.PreSaveValidateException;
import com.threeti.mecool.legacy.infrastructure.persistence.BrandCategoryLegacyRepository;
import com.threeti.mecool.legacy.infrastructure.persistence.BrandLegacyRepository;
import com.threeti.mecool.legacy.infrastructure.persistence.ProductLegacyRepository;
import org.springframework.beans.factory.annotation.Configurable;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.Date;

@Configurable
@Entity
@Table(name = "DM_PROJECT_STORE_SV")
public class ProjectStoreSellingValue {
    ProductLegacyRepository productLegacyRepository;
    BrandCategoryLegacyRepository brandCategoryLegacyRepository;
    BrandLegacyRepository brandLegacyRepository;

    private Long id;
    private Integer version;
    private ProjectStore projectStore;
    private ProjectProductCollectionType uploadType;
    private String categoryCode;
    private String brandCode;
    private String skuCode;
    private double summary;
    private double price;
    private double amount;
    private String amountUnit;
    private Date sellDate;
    private Date updatedAt;
    private User updatedBy;

    static class Builder {
        private ProjectStore projectStore;
        private ProjectProductCollectionType uploadType;
        private Date sellDate;
        private Date updatedAt;
        private User updatedBy;
        private String categoryCode;
        private String brandCode;
        private String skuCode;
        private double summary;
        private double price;
        private double amount;
        private String amountUnit;

        public Builder(ProjectStore projectStore, ProjectProductCollectionType uploadType, Date updatedAt, User updatedBy, Date sellDate) {
            this.projectStore = projectStore;
            this.uploadType = uploadType;
            this.updatedAt = updatedAt;
            this.updatedBy = updatedBy;
            this.sellDate = sellDate;
        }

        public ProjectStoreSellingValue build() {
            if (projectStore == null || uploadType == null || updatedBy == null || sellDate == null) {
                throw new PreSaveValidateException("projectStore, uploadType, updatedBy, sellDate 不能为空");
            }
            return new ProjectStoreSellingValue(this);
        }

        public Builder code(String val) {
            switch (uploadType) {
                case CATEGORY: categoryCode = val; break;
                case BRAND: brandCode = val; break;
                case SKU: skuCode = val; break;
                default: throw new PreSaveValidateException("无效的上传方式，需要[CATEGORY, BRAND, SKU]");
            }
            return this;
        }
        public Builder summary(Number val) {summary = val != null ? val.doubleValue() : 0; return this;}
        public Builder price(Number val) {price = val != null ? val.doubleValue() : 0; return this;}
        public Builder amount(Number val) {amount = val != null ? val.doubleValue() : 0; return this;}
        public Builder amountUnit(String val) {amountUnit = val; return this;}
    }

    public ProjectStoreSellingValue() {
    }

    private ProjectStoreSellingValue(Builder builder) {
        this.projectStore = builder.projectStore;
        this.uploadType = builder.uploadType;
        this.categoryCode = builder.categoryCode;
        this.brandCode = builder.brandCode;
        this.skuCode = builder.skuCode;
        this.summary = builder.summary;
        this.price = builder.price;
        this.amount = builder.amount;
        this.amountUnit = builder.amountUnit;
        this.sellDate = builder.sellDate;
        this.updatedAt = builder.updatedAt != null ? builder.updatedAt : new Date();
        this.updatedBy = builder.updatedBy;
    }

    @PrePersist @PreUpdate
    public void validate() {
        switch (uploadType) {
            case CATEGORY:
                if (null == brandCategoryLegacyRepository.findOne(categoryCode)) {
                    throw new PreSaveValidateException("无效的品类代码 - " + categoryCode);
                }
            case BRAND:
                if (null == brandLegacyRepository.findOne(brandCode)) {
                    throw new PreSaveValidateException("无效的品牌代码 - " + brandCode);
                }
            case SKU:
                if (null == productLegacyRepository.findOne(skuCode)) {
                    throw new PreSaveValidateException("无效的SKU代码 - " + skuCode);
                }
            default:
                throw new PreSaveValidateException("无效的上传方式，需要[CATEGORY, BRAND, SKU]");
        }
    }

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    public Long getId() {
        return id;
    }

    @Version
    public Integer getVersion() {
        return version;
    }

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    public ProjectStore getProjectStore() {
        return projectStore;
    }

    @NotNull
    @Enumerated(EnumType.STRING)
    public ProjectProductCollectionType getUploadType() {
        return uploadType;
    }

    public String getCategoryCode() {
        return categoryCode;
    }

    public String getBrandCode() {
        return brandCode;
    }

    public String getSkuCode() {
        return skuCode;
    }

    public double getSummary() {
        return summary;
    }

    public double getPrice() {
        return price;
    }

    public double getAmount() {
        return amount;
    }

    public String getAmountUnit() {
        return amountUnit;
    }

    @NotNull
    @Temporal(TemporalType.DATE)
    public Date getSellDate() {
        return sellDate;
    }

    @Temporal(TemporalType.TIMESTAMP)
    public Date getUpdatedAt() {
        return updatedAt;
    }

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    public User getUpdatedBy() {
        return updatedBy;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public void setProjectStore(ProjectStore projectStore) {
        this.projectStore = projectStore;
    }

    public void setUploadType(ProjectProductCollectionType uploadType) {
        this.uploadType = uploadType;
    }

    public void setCategoryCode(String categoryCode) {
        this.categoryCode = categoryCode;
    }

    public void setBrandCode(String brandCode) {
        this.brandCode = brandCode;
    }

    public void setSkuCode(String skuCode) {
        this.skuCode = skuCode;
    }

    public void setSummary(double summary) {
        this.summary = summary;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public void setAmount(double amount) {
        this.amount = amount;
    }

    public void setAmountUnit(String amountUnit) {
        this.amountUnit = amountUnit;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    public void setUpdatedBy(User updatedBy) {
        this.updatedBy = updatedBy;
    }

    public void setSellDate(Date sellDate) {
        this.sellDate = sellDate;
    }
}
